#include <time.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./client/Client.h"
#include "./serveur/Serveur.h"
#include "./fabricant/Fabricant.h"
#include "./routeur/Routeur.h"
#include "./Message.h"
#include "./Annuaire.h"

#define SIZE_CONTENU (S_CONTENT-NB_ROUTEURS_MAX*(S_URL+S_PORT)-1)

Annuaire A;

void* traitement(void *t)
{
	Message m;
	while (1){
		m=get(&A,(int) t);
		fabricantCreerOignon(&(A.f),&m);
		A.c.communiquer(message_destinataire(&m),message_port(&m),m);
	}
}

void* direction(void*t)
{
	Message m;
	while(1)
	{
		m=A.s.connexion();
		messageDecrypter(&m,_clef(20));
		messageAfficher(&m);
		put(&A,m);
	}
}


int main (int argc, char *argv[])
{
	srand(time(NULL));


	char* port_recepteur=(char*)"9999";
	const char* port_fabricant="2222";
	char url_fabricant[S_URL];
	system("clear");
	char* menu;
	menu=(char *)"0";
	menu = (char *) malloc(sizeof(char));
	while(*menu!='9')
	{
		printf("saisir le menu\n");
		printf("0 - Démarrage du Serveur\n");
		printf("1 - Démarrage de l'Emmeteur\n");
		printf("2 - Démarrage du Recepteur\n");
		printf("3 - Démarrage d'un Routeur\n");
		printf("4 - Regénération des clefs\n");
		printf("9 - Quitter\n");
		fgets(menu,sizeof(int),stdin);
		if(*menu=='0')
		{
			//c'est le serveur

			AnnuaireInit(&A);

			// Création des threads
			pthread_t ouvriers[NB_OUVRIERS];
			pthread_t manager;
			pthread_attr_t attr;

			/* For portability, explicitly create threads in a joinable state */
			pthread_attr_init(&attr);
			pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

			pthread_create(&manager, &attr,direction,(void*)-1);

			for(int i=0; i<NB_OUVRIERS; i++)
			{
				pthread_create(&ouvriers[i], &attr,traitement, (void *)i);
			}

			pthread_join(manager,NULL);
			for(int i=0; i<NB_OUVRIERS; i++)
			{
				pthread_join(ouvriers[i],NULL);
			}


		}
		else if(*menu=='1')
		{
			printf("\n DEMARRAGE DE L'EMMETEUR\n");
			Message monMessage;
			Client c;
			int lg,nb,debut,fin;
			char *dest,*port,*contenu,*fichier;
			dest=(char*)malloc(sizeof(char)*S_URL);
			port=(char*)malloc(sizeof(char)*S_PORT);
			contenu=(char*)malloc(sizeof(char)*10000);
			fichier=(char*)malloc(sizeof(char)*20);
			printf("Saisir l'url du fabricant\n");

			fgets(url_fabricant,S_URL,stdin);
			strtok(url_fabricant, "\n");
			
			while(1)
			{


				//  messageSaisir(&monMessage);
				messageSaisirDestinataire(dest);
			//	messageSaisirPort(port);
				messageSaisirContenu(contenu);
				//messageCharger(&monMessage,(char*)"monFichier.txt");
				lg=strlen(contenu);
				nb = int(lg/SIZE_CONTENU);
				//printf("la taille maximum du contenu est : %d \n",SIZE_CONTENU);  
				printf("la taille du contenu est : %d et il y aura %d message(s)\n",lg,nb);
				for(int i=0;i<=nb;i++)
				{
					sprintf(fichier, "message-%d.txt",i);
					debut=i*SIZE_CONTENU;
					fin=(i+1)*SIZE_CONTENU;
					char temp [SIZE_CONTENU+1];
					temp[fin+1-debut]='\0';
					//printf("debut vaut %d et fin vaut %d \n",debut,fin);
					memcpy(temp,(char *)contenu+debut,fin-debut);
					//printf("dest vaut %s \nle port vaut %s \nle contenu '%s'\nle numero %d et le nombre %d \n",dest,port,temp,i+1,nb);
					messageInit(&monMessage,temp,dest,port_recepteur,i,nb);
					messageAfficher(&monMessage);
					messageSauvegarder(&monMessage,fichier);
					messageCrypter(&monMessage,_clef(20));
					c.communiquer(url_fabricant,port_fabricant,monMessage);
				}

			}
		}
		else if(*menu=='2')
		{
			printf("\nDEMARRAGE DU RECEPTEUR\n");
			Serveur s;
			const char* port=port_recepteur;

			s.demarrer(port);
			while(1)
			{

				Message monMessage=s.connexion();
				messageDecrypter(&monMessage,_clef(21));
				messageAfficher(&monMessage);
			}
			s.eteindre();

		}
		else if(*menu =='3')
		{
			printf("\nDEMARRAGE D'UN ROUTEUR\n");
			printf("saisir l'id du Routeur(cf fabricant)\n");
			char cid[3];
			fgets(cid,3,stdin);
			//strtok(cid, "\n");
			int id;
			id=atoi(cid);
			char port[S_PORT];
			char url[S_URL];
			FILE* fichier;
			fichier=fopen("fabricant.txt","r");
			printf("\nINITIALISATION DU ROUTEUR\n");
			for(int i=0;i<id;i++)
			{	
				fgets(url,S_URL,fichier);
				strtok(url, "\n");
				fgets(port,S_PORT, fichier);
				strtok(port, "\n");

			}
			fclose(fichier);;
			printf( "n°%d url:%s port:%s\n",id, url,port);
			Routeur monRouteur;
			routeurInit(&monRouteur,id, url, port);
			routeurDemarrer(&monRouteur);

		}
		else if(*menu=='4')
		{
			sauvClefs();
		}

	}

	return 0;
}
